package com.sh.data.engine.application.service.api;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sh.data.engine.application.model.dto.api.*;
import com.sh.data.engine.application.model.dto.common.DirectoryResponse;
import com.sh.data.engine.application.model.dto.integration.DataSourceDTO;
import com.sh.data.engine.application.model.request.api.DataApiCallRecordRequest;
import com.sh.data.engine.common.util.ServletUtils;
import com.sh.data.engine.domain.api.model.domain.*;
import com.sh.data.engine.domain.api.model.domain.rest.DataApiCallSummaryDomain;
import com.sh.data.engine.domain.api.model.param.DataApiCallRecordParam;
import com.sh.data.engine.domain.api.service.DataApiCallRecordService;
import com.sh.data.engine.domain.api.service.DataApiOverviewService;
import com.sh.data.engine.domain.api.service.DataApiService;
import com.sh.data.engine.domain.base.model.PageResult;
import com.sh.data.engine.domain.base.model.UserContext;
import com.sh.data.engine.domain.base.model.enums.DirectoryMenuEnum;
import com.sh.data.engine.domain.common.model.domain.DirectoryDomain;
import com.sh.data.engine.domain.common.service.DirectoryService;
import com.sh.data.engine.domain.integration.datasource.model.domain.DataSourceDomain;
import com.sh.data.engine.domain.integration.datasource.service.DataSourceService;
import com.sh.data.engine.domain.util.ConvertUtil;
import com.sh.data.engine.domain.workspace.manager.model.domain.UserDomain;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: mengzheng.mhc
 * @date: 2024/8/15 15:52
 */
@Slf4j
@Service
public class DataApiOverviewApplicationService {

    @Autowired
    private DataApiOverviewService dataApiOverviewService;

    @Autowired
    private DataApiCallRecordService dataApiCallRecordService;

    @Autowired
    private DataApiService dataApiService;

    @Autowired
    private DataSourceService dataSourceService;

    @Autowired
    private DirectoryService directoryService;

    public boolean getLocalUserAuth() {
        UserDomain userInfo = UserContext.getUserInfo();
        Integer isAuth = userInfo.getIsAuth();
        return null != isAuth && !isAuth.equals(0);
    }

    public DataApiOverviewSummaryResponse getOverviewSummary(Integer type) {
        UserDomain userInfo = UserContext.getUserInfo();
        Long projectId = ServletUtils.getProjectId();
        String id = userInfo.getId();
        Integer isAuth = userInfo.getIsAuth();
        DataApiOverviewSummaryDomain summaryDomain =
            dataApiOverviewService.getOverviewSummary(type, projectId, id, isAuth);

        return ConvertUtil.copyProperties(summaryDomain, DataApiOverviewSummaryResponse.class);
    }

    public DataApiApprovalSummaryResponse getApprovalSummary(Integer type) {
        UserDomain userInfo = UserContext.getUserInfo();
        Long projectId = ServletUtils.getProjectId();
        String id = userInfo.getId();
        Integer isAuth = userInfo.getIsAuth();
        DataApiApprovalSummaryDomain dataApiApprovalSummaryDomain =
            dataApiOverviewService.getApprovalSummary(type, projectId, id, isAuth);

        return ConvertUtil.copyProperties(
            dataApiApprovalSummaryDomain, DataApiApprovalSummaryResponse.class);
    }

    public List<DataApiReqTrendSummaryResponse> getReqTrendSummary(Integer type, String startDate, String endDate) {
        UserDomain userInfo = UserContext.getUserInfo();
        Long projectId = ServletUtils.getProjectId();
        String id = userInfo.getId();
        Integer isAuth = userInfo.getIsAuth();
        List<DataApiReqTrendSummaryDomain> reqTrendSummary =
            dataApiOverviewService.getReqTrendSummary(type, startDate, endDate, projectId, isAuth, id);

        return ConvertUtil.copyProperties(reqTrendSummary, DataApiReqTrendSummaryResponse.class);
    }

    public Map<String, Object> getTopUserReqSummary() {
        Long projectId = ServletUtils.getProjectId();

        List<DataApiTopUserReqSummaryDomain> domains =
            dataApiOverviewService.getTopUserReqSummary(projectId);

        List<DataApiTopUserReqSummaryResponse> responses =
            ConvertUtil.copyProperties(domains, DataApiTopUserReqSummaryResponse.class);

        long total =
            domains.stream()
                .filter(Objects::nonNull)
                .mapToLong(DataApiTopUserReqSummaryDomain::getTotalCount)
                .sum();

        // 前端需要这种格式
        Map<String, Object> map = new HashMap<>();
        map.put("list", responses);
        map.put("total", total);
        return map;
    }

    public Map<String, Object> getTopApiReqSummary(Integer type) {
        UserDomain userInfo = UserContext.getUserInfo();
        Long projectId = ServletUtils.getProjectId();

        List<DataApiTopApiReqSummaryDomain> domains =
            dataApiOverviewService.getTopApiReqSummary(
                type, projectId, userInfo.getIsAuth(), userInfo.getId());

        long total =
            domains.stream()
                .filter(Objects::nonNull)
                .mapToLong(DataApiTopApiReqSummaryDomain::getTotalCount)
                .sum();
        List<DataApiTopApiReqSummaryResponse> responses =
            ConvertUtil.copyProperties(domains, DataApiTopApiReqSummaryResponse.class);
        // 前端需要这种格式
        Map<String, Object> map = new HashMap<>();
        map.put("list", responses);
        map.put("total", total);
        return map;
    }

    public Map<String, Object> getTopApiErrReqSummary(Integer type) {
        UserDomain userInfo = UserContext.getUserInfo();
        Long projectId = ServletUtils.getProjectId();

        List<DataApiTopApiReqSummaryDomain> domains =
            dataApiOverviewService.getTopApiErrReqSummary(
                type, projectId, userInfo.getIsAuth(), userInfo.getId());
        long total =
            domains.stream()
                .filter(Objects::nonNull)
                .mapToLong(DataApiTopApiReqSummaryDomain::getTotalCount)
                .sum();
        List<DataApiTopApiReqSummaryResponse> responses =
            ConvertUtil.copyProperties(domains, DataApiTopApiReqSummaryResponse.class);

        // 前端需要这种格式
        Map<String, Object> map = new HashMap<>();
        map.put("list", responses);
        map.put("total", total);
        return map;
    }

    public Map<String, Object> getErrDistributionSummary(Integer type) {
        UserDomain userInfo = UserContext.getUserInfo();
        Long projectId = ServletUtils.getProjectId();

        List<DataApiErrDistributionSummaryDomain> errDistributionSummary =
            dataApiOverviewService.getErrDistributionSummary(
                type, projectId, userInfo.getIsAuth(), userInfo.getId());

        List<DataApiErrDistributionSummaryResponse> dataApiErrDistributionSummaryResponses =
            ConvertUtil.copyProperties(
                errDistributionSummary, DataApiErrDistributionSummaryResponse.class);
        long total =
            dataApiErrDistributionSummaryResponses.stream()
                .filter(Objects::nonNull)
                .mapToLong(DataApiErrDistributionSummaryResponse::getValue)
                .sum();
        Map<String, Object> map = new HashMap<>();
        map.put("list", dataApiErrDistributionSummaryResponses);
        map.put("total", total);
        return map;
    }

    public PageResult<DataApiCallRecordResponse> listDataApiRecord(DataApiCallRecordRequest recordRequest) {
        DataApiCallRecordParam convert = Convert.convert(DataApiCallRecordParam.class, recordRequest);
        IPage<DataApiCallSummaryDomain> domainIPage = dataApiCallRecordService.listDataApiRecord(
            convert);
        PageResult<DataApiCallRecordResponse> dataApiCallRecordResponsePageResult = PageResult.copyPropertiesAndConvert(
            domainIPage, DataApiCallRecordResponse.class);

        return dataApiCallRecordResponsePageResult;
    }

    public List<DataSourceDTO> listDsName() {
        Long projectId = ServletUtils.getProjectId();
        List<DataSourceDomain> dataSourceDomains = dataSourceService.getAllByProject(projectId);
        return Convert.toList(DataSourceDTO.class, dataSourceDomains);
    }

    public List<DirectoryResponse> listDirName() {
        Long projectId = ServletUtils.getProjectId();
        List<DirectoryDomain> dirList = directoryService.getDirList(projectId, DirectoryMenuEnum.API,
            null);
        return Convert.toList(DirectoryResponse.class, dirList);
    }

    public boolean batchIgnored(String ids) {
        if (StringUtils.isNotBlank(ids)) {
            List<Long> collect = Arrays.stream(ids.split(",")).map(Long::valueOf)
                .collect(Collectors.toList());
            dataApiCallRecordService.batchIgnored(collect);
        }
        return true;
    }

    public DataApiLogResponse getRequestLog(Long logId, Integer offset) {
        DataApiLogDomain requestLog = dataApiService.getRequestLog(logId, offset);
        return ConvertUtil.copyProperties(requestLog, DataApiLogResponse.class);
    }
}
